Kokaの例: Exception
raise effectを定義
code:koka(js)
effect ctl raise(msg: string): int
effec type名とoperation名を同じにすることで簡潔に書けるmrsekut.icon
raise effectを持つ関数を定義
code:koka(ts)
fun safe-divide(x: int, y: int): raise int
if y==0 then raise("div-by-zero") else x / y
安全に除算する関数
この時点では、raise()を呼んだときに、何を行うのかは定義されていないmrsekut.icon
handlerを用いてsafe-divideを使用する
code:koka(ts)
fun raise-const(): int
with ctl raise(msg) 42 // ①
8 + safe-divide(1,0) // ②
①で、raiseのhandlerとして定数42を返す処理を書く
②で実際に処理が実行されるが、
safe-divideの中でraiseが呼ばれ、①に到達し、
最終的な結果は42になる
resumeしてみる
code:koka(ts)
fun raise-resume()
with ctl raise(msg) resume(42)
8 + safe-divide(1,0)
handlerの中でresumeを呼ぶことで処理を再開し、最終的な結果は8 + 42で50になる
ちなみに、with funを使って以下のようにも書ける
code:koka(ts)
fun raise-resume()
with fun raise(msg) 42
8 + safe-divide(1,0)
やや簡潔mrsekut.icon
おしゃれなabstraction handlerを用意しておく
code:koka(ts)
fun catch(hnd: (string) -> e a, action: () -> <raise|e> a): e a
with ctl raise(msg) hnd(msg)
action()
以下のように、親しい例であるerror handlingが書ける
code:koka(ts)
fun use-catch()
with catch fn(msg)
println("error: " ++ msg); 42
safe-divide(1,0)
よく見るやつmrsekut.icon
try節とcatch節が逆になっているね
code:use-catch()を実行しraiseした場合の結果
error: div-by-zero
42